﻿using System;
using System.Text;
using System.Data;
using System.Data.OleDb;

namespace MyFastDataSourceBind
{
    /// <summary>
    /// 操作数据库的例程，编写 袁永福
    /// </summary>
    /// <remarks>
    /// 本类型定义了一些程序框架操作数据库时需要调用的例程，该类型的所有成员都是静态的，
    /// 为了兼容C#1.1，不将本类型定义为静态类。
    /// </remarks>
    public class ConnectionHelper
    {
        /// <summary>
        /// 本对象不能实例化
        /// </summary>
        private ConnectionHelper()
        {
        }

        private static OleDbConnection myConnection = null;
        /// <summary>
        /// 获得数据库连接对象
        /// </summary>
        public static OleDbConnection Connection
        {
            get
            {
                if (myConnection == null)
                {
                    myConnection = new OleDbConnection();
                    // 
                    // 此时诸如下面的代码来设置数据库连接字符串是无效的
                    //myConnection.ConnectionString = 
                    //    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
                    //    + System.IO.Path.Combine(
                    //    System.Windows.Forms.Application.StartupPath, 
                    //    "SkyDemo.mdb");

                    // 由于程序框架在设计时就访问本属性，而此时应用程序尚未运行甚至EXE文件还未生成，
                    // 此时System.Windows.Forms.Application.StartupPath属性值是无效的，因此无法使用
                    // 诸如 "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="
                    //    + System.IO.Path.Combine(
                    //    System.Windows.Forms.Application.StartupPath,"SkyDemo.mdb")
                    // 之类的方法来拼凑数据库连接字符串，此时可以在应用程序配置文件中写明数据库连接
                    // 字符串。因为配置文件中的字符串在设计时是有效的可以访问的。
                    // 
                    myConnection.ConnectionString =
                        MyFastDataSourceBind.Properties.Settings.Default.MainConnectionString;
                    myConnection.Open();
                }
                return myConnection;
            }
        }


        private static XDesignerData.DataBaseInfo myDBInfo = null;
        /// <summary>
        /// 获得数据库信息对象,能获得数据库的表和字段结构，为程序框架的设计时提供支持
        /// </summary>
        public static XDesignerData.DataBaseInfo DBInfo
        {
            get
            {
                if (myDBInfo == null)
                {
                    myDBInfo = new XDesignerData.DataBaseInfo();
                    myDBInfo.LoadFromAccess2000(Connection);
                }
                return myDBInfo;
            }
        }

        /// <summary>
        /// 关闭数据库连接对象
        /// </summary>
        public static void CloseConnection()
        {
            if (myConnection != null)
            {
                if (myConnection.State == ConnectionState.Open)
                {
                    myConnection.Close();
                }
                myConnection.Dispose();
                myConnection = null;
            }
        }

        /// <summary>
        /// 查询数据并将查询结果填充到一个数据表对象中然后返回该数据表对象
        /// </summary>
        /// <param name="cmdInfo">查询命令信息对象</param>
        /// <returns>获得的数据表对象</returns>
        public static System.Data.DataTable ReadDataTable(XDBCommandInfo cmdInfo)
        {
            // 创建数据库命令对象
            using (OleDbCommand cmd = (OleDbCommand)cmdInfo.CreateCommand(Connection))
            {
                // 创建数据库适配器
                OleDbDataAdapter adp = new OleDbDataAdapter();
                adp.SelectCommand = cmd;
                // 创建一个临时的数据集
                System.Data.DataSet ds = new System.Data.DataSet();
                // 查询数据库并填充数据集
                adp.Fill(ds);
                if (ds.Tables.Count > 0)
                {
                    // 返回查询结果
                    return ds.Tables[0];
                }
            }
            return null;
        }


        /// <summary>
        /// 查询数据库，并将查询结果填充到一个DataTable对象中然后返回该数据表对象。
        /// </summary>
        /// <param name="strSQL">查询数据使用的SQL文本</param>
        /// <returns>获得的数据表对象</returns>
        public static System.Data.DataTable ReadDataTable(string strSQL)
        {
            using (OleDbCommand cmd = Connection.CreateCommand())
            {
                cmd.CommandText = strSQL;
                OleDbDataAdapter adp = new OleDbDataAdapter();
                adp.SelectCommand = cmd;
                System.Data.DataSet ds = new System.Data.DataSet();
                adp.Fill(ds);
                if (ds.Tables.Count > 0)
                {
                    return ds.Tables[0];
                }
            }
            return null;
        }

        /// <summary>
        /// 创建字段值
        /// </summary>
        /// <param name="TableName">数据表名</param>
        /// <param name="FieldName">数据字段名</param>
        /// <returns>创建的字段值</returns>
        public static int GenerateID(string TableName, string FieldName)
        {
            using (IDbCommand cmd = Connection.CreateCommand())
            {
                cmd.CommandText = "Select Max( " + FieldName + " ) From " + TableName;
                object obj = cmd.ExecuteScalar();
                if (obj == null || DBNull.Value.Equals(obj))
                    return 0;
                else
                    return Convert.ToInt32(obj) + 1;
            }
        }

        /// <summary>
        /// 执行SQL更新
        /// </summary>
        /// <param name="cmdInfo">查询命令信息对象</param>
        /// <returns>操作影响的数据库记录个数</returns>
        public static int ExecuteNonQuery(XDBCommandInfo cmdInfo)
        {
            using (IDbCommand cmd = cmdInfo.CreateCommand(Connection))
            {
                int result = cmd.ExecuteNonQuery();
                return result;
            }
        }

        /// <summary>
        /// 更新数据源的数据
        /// </summary>
        /// <param name="ds">数据源对象</param>
        /// <returns>影响的数据库记录的个数</returns>
        public static int UpdateDataSource(XDataSource ds)
        {
            // 检查参数
            if (ds == null)
            {
                throw new ArgumentNullException("ds");
            }
            if (ds.DataTable == null)
            {
                throw new InvalidOperationException("DataTable is null");
            }
            // 使用数据适配器更新数据库
            using (OleDbDataAdapter adapter = new OleDbDataAdapter())
            {
                if (ds.DeleteCommand != null)
                {
                    // 创建删除数据用的SQL命令对象
                    adapter.DeleteCommand = (OleDbCommand)ds.DeleteCommand.CreateCommand(Connection);
                }
                if (ds.InsertCommand != null)
                {
                    // 创建插入数据用的SQL命令对象
                    adapter.InsertCommand = (OleDbCommand)ds.InsertCommand.CreateCommand(Connection);
                }
                if (ds.UpdateCommand != null)
                {
                    // 创建更新数据用的SQL命令对象
                    adapter.UpdateCommand = (OleDbCommand)ds.UpdateCommand.CreateCommand(Connection);
                }
                // 更新数据
                return adapter.Update(ds.DataTable);
            }
        }


        /// <summary>
        /// 判断两个字段名是否等价
        /// </summary>
        /// <param name="name1">字段名1</param>
        /// <param name="name2">字段名2</param>
        /// <returns>是否等价</returns>
        public static bool CompareFieldName(string name1, string name2)
        {
            if (name1 != null)
                name1 = name1.Trim();
            if (name2 != null)
                name2 = name2.Trim();
            if (name1 == name2)
            {
                return true;
            }
            if (string.Compare(name1, name2, true) == 0)
            {
                return true;
            }
            int index = name1.IndexOf(".");
            if (index >= 0)
            {
                name1 = name1.Substring(index + 1);
            }
            index = name2.IndexOf(".");
            if (index >= 0)
            {
                name2 = name2.Substring(index + 1);
            }
            if (string.Compare(name1, name2, true) == 0)
            {
                return true;
            }
            return false;
        }
    }
}